package edu.neu.cloud_factory.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import edu.neu.cloud_factory.dao.UserMapper;
import edu.neu.cloud_factory.entity.po.*;
import edu.neu.cloud_factory.dao.DeviceMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.neu.cloud_factory.entity.vo.DeviceVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 设备 服务实现类
 * </p>
 *
 * @author halozhy
 * @since 2021-07-15
 */
@Slf4j
@Service
public class DeviceService extends ServiceImpl<DeviceMapper, Device> implements IService<Device> {
    @Autowired
    DeviceMapper deviceMapper;

    @Autowired
    DeviceTypeService deviceTypeService;

    @Autowired
    ScheduleService scheduleService;

    @Autowired
    UserMapper userMapper;

    @Autowired
    BidService bidService;

    @Autowired
    OrderService orderService;

    @Autowired
    NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    public List<Device> selectDeviceByDeviceTypeId(int dtId) {
        // 查询设备类型下已关联的设备
        Map<String, Object> colMap = new HashMap<>();
        colMap.put("d_type_id", dtId);
        return deviceMapper.selectByMap(colMap);
    }

    public JSONObject listDevice(Integer page, Integer limit, String id, String name, String describe) {
        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        if (id != null && !id.isEmpty()) {
            queryWrapper.like("d_id", id);
        }
        if (name != null && !name.isEmpty()) {
            queryWrapper.like("d_name", name);
        }
        if (describe != null && !describe.isEmpty()) {
            queryWrapper.like("d_describe", describe);
        }

        List<Device> deviceList = deviceMapper.listPage((page - 1) * limit, limit, queryWrapper);
        List<DeviceVo> deviceVoList = new ArrayList<>();
        List<DeviceType> deviceTypeList = deviceTypeService.list();
        deviceList.forEach(device -> {
            DeviceVo deviceVo = new DeviceVo();
            deviceVo.setId(device.getDId());
            deviceVo.setName(device.getDName());
            deviceVo.setSpec(device.getDSpec());
            deviceVo.setState(device.getDState());
            deviceVo.setDescribe(device.getDDescribe());
            deviceVo.setType_id(device.getDTypeId());
            deviceVo.setDept_name(device.getDDeptName());
            deviceVo.setRent_rec_id(device.getDRentRecId());
            for (DeviceType dt :
                    deviceTypeList) {
                if (dt.getDtId().equals(device.getDTypeId())) {
                    deviceVo.setType_name(dt.getDtName());
                    break;
                }
            }
            deviceVoList.add(deviceVo);
        });
        JSONObject result = new JSONObject();
        result.put("data", deviceVoList);
        result.put("count", deviceMapper.selectCount(queryWrapper));
        return result;
    }

    public int shutdown(Integer id) {
        // 0 ok -1 无此设备 -2 此设备已经关机 -3 有排产计划，不允许关机
        Device d = deviceMapper.selectById(id);
        if (d == null) {
            return -1;
        } else {
            List<Schedule> scheduleList = scheduleService.selectScheduleListByDId(d.getDId());
            for (Schedule schedule :
                    scheduleList) {
                Bid b = bidService.getById(schedule.getSBidId());
                Order o = orderService.getById(b.getBOrderId());
                if (o.getOState().equals("已生产")) {
                    log.info("发现仍处于生产的订单和排产计划：schedule id: {}, order id: {}", schedule.getSId(), o.getOId());
                    return -3;
                }
            }

            if (d.getDState().equals("闲置")) {
                d.setDState("关机");
                deviceMapper.updateById(d);
                return 0;
            } else if (d.getDState().equals("关机")) {
                return -2;
            } else if (d.getDState().equals("开机")) {
                d.setDState("关机");
                deviceMapper.updateById(d);
                return 0;
            } else {
                return -4;
            }
        }
    }

    public int open(Integer id) {
        // 0 ok -1 无此设备 -2 此设备已经是闲置状态
        Device d = deviceMapper.selectById(id);
        if (d == null) {
            return -1;
        } else {
            if (d.getDState().equals("关机")) {
                d.setDState("闲置");
                deviceMapper.updateById(d);
                return 0;
            } else if (d.getDState().equals("闲置")) {
                return -2;
            } else {
                return -3;
            }
        }
    }

    public JSONObject listDeviceFac(Integer page, Integer limit, String id, String name, String describe, String user_id) {
        // 此处的逻辑有些复杂，构造的wrapper 不能处理 where ( x or x ) and x and 这种情况
        //
        User u = userMapper.selectById(user_id);

        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("r_factory_id", u.getUFactoryId())
//                .or().eq("d_factory_id", u.getUFactoryId());

        if (id != null && !id.isEmpty()) {
            queryWrapper.like("d_id", id);
        }
        if (name != null && !name.isEmpty()) {
            queryWrapper.like("d_name", name);
        }
        if (describe != null && !describe.isEmpty()) {
            queryWrapper.like("d_describe", describe);
        }
        queryWrapper.and(i -> i.eq("r_factory_id", u.getUFactoryId())
                .or().eq("d_factory_id", u.getUFactoryId()));

        List<Device> deviceList = deviceMapper.listPageJoinRentRec((page - 1) * limit, limit, queryWrapper);
//        List<Device> deviceListResult = new ArrayList<>();
//        for (Device device : deviceList) {
//            if (id != null && !id.isEmpty() && !String.valueOf(device.getDId()).contains(id)) {
//                continue;
//            }
//            if (name != null && !name.isEmpty() && !device.getDName().contains(name)) {
//                continue;
//            }
//            if (describe != null && !describe.isEmpty() && !device.getDDescribe().contains(describe)) {
//                continue;
//            }
//            deviceListResult.add(device);
//        }
        List<DeviceVo> deviceVoList = new ArrayList<>();
        List<DeviceType> deviceTypeList = deviceTypeService.list();
        for (int i = 0; i < deviceList.size(); i++) {
            Device device = deviceList.get(i);
            DeviceVo deviceVo = new DeviceVo();
            deviceVo.setId(device.getDId());
            deviceVo.setName(device.getDName());
            deviceVo.setSpec(device.getDSpec());
            deviceVo.setState(device.getDState());
            deviceVo.setDescribe(device.getDDescribe());
            deviceVo.setType_id(device.getDTypeId());
            deviceVo.setDept_name(device.getDDeptName());
            deviceVo.setRent_rec_id(device.getDRentRecId());
            for (DeviceType dt :
                    deviceTypeList) {
                if (dt.getDtId().equals(device.getDTypeId())) {
                    deviceVo.setType_name(dt.getDtName());
                    break;
                }
            }
            deviceVoList.add(deviceVo);
        }
        JSONObject result = new JSONObject();
        result.put("data", deviceVoList);
        result.put("count", deviceMapper.listCountJoinRentRec(queryWrapper));
        return result;
    }


    public List<Device> listJoinRentRec(QueryWrapper queryWrapper) {
        return deviceMapper.listJoinRentRec(queryWrapper);
    }
}
